package medium;

/**
 * Created by daodao on 2017/11/30.
 * Problem 8
 * Description: Implement atoi to convert a string to an integer.
 *
 * Hint: Carefully consider all possible input cases.
 * If you want a challenge, please do not see below and ask yourself what are the possible input cases.
 *
 * Notes: It is intended for this problem to be specified vaguely (ie, no given input specs).
 * You are responsible to gather all the input requirements up front.
 */
public class StringToInteger {
    public static int myAtoi(String str) {
        String src = str.trim();
        if (src == null || "".equals(src)) {
            return 0;
        }
        char[] chars = src.toCharArray();
        int result = 0;
        boolean isPositive;
        int negCnt = 0;
        int posCnt = 0;
        int spaceCnt = 0;
        int i = 0;
        while (i < chars.length && (chars[i] == '+' || chars[i] == '-' || chars[i] == ' ')) {
            if (chars[i] == '+') {
                posCnt++;
            }
            if (chars[i] == '-') {
                negCnt++;
            }
            if (chars[i] == ' ') {
                spaceCnt++;
            }
            i++;
        }
        if (spaceCnt > 0 || posCnt + negCnt >= 2) {
            return 0;
        }
        isPositive = posCnt >= negCnt ? true : false;
        int limit = Integer.MAX_VALUE;
        chars = src.substring(posCnt + negCnt).toCharArray();
        int bit = 0;
        if (chars.length > 0) {
            // 确定有效位数bit
            while(bit < chars.length && chars[bit] >= '0' && chars[bit] <= '9') {
                bit++;
            }
            if (bit > 10) {
                return isPositive ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            }
            // 防止溢出 int_max = 2147483647, int_min = -2147483648
            int multmin = limit / 10;
            // '0': 48
            for (int j = 0; j < bit; j++) {
                int digit = chars[j] - 48;
                if (result >= multmin) {
                    if (digit > 7 || result > multmin) {
                        return isPositive ? Integer.MAX_VALUE : Integer.MIN_VALUE;
                    }
                }
                result *= 10;
                result += digit;
            }
        }
        return isPositive ? result : - result;
    }
}
